﻿//========================================================= 
/**@file ApplePay.h
 * @brief ApplePay支付读取卡号
 * 
 * @date 2017-09-11   14:12:25
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_APPLEPAY_H_
#define _LIBZHOUYB_APPLEPAY_H_
//--------------------------------------------------------- 
#include "../../device/iccard/pboc/v2_0/PBOC_v2_0_AppAdapter.h"
using namespace zhou_yb::device::iccard::pboc;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace pboc {
//--------------------------------------------------------- 
/**
 * @brief ApplePay支付获取卡号
 * @date 2017-09-11 14:53
 */
class ApplePayAppAdapter : public PBOC_v2_0_BaseAdapter
{
public:
    ApplePayAppAdapter() : PBOC_v2_0_BaseAdapter() {}
    /**
     * @brief 获取ApplePay卡号
     * @date 2017-09-11 14:54
     * 
     * @param [out] cardNumber 获取到的卡号
     * @param [out] appData 获取到的应用数据
     * @param [in] terminalVal [default:""] 终端TLV数据
     */
    bool GetCardNumber(ByteBuilder& cardNumber, ByteBuilder& appData, const ByteArray& terminalVal = "")
    {
        LOG_FUNC_NAME();
        ASSERT_Device();

        // 优先从 PPSE 枚举子应用
        list_t<PBOC_Library::AID> aidlist;
        ByteBuilder aidData(16);
        TlvElement tlv;
        TlvElement subTlv;

        ByteBuilder cmd(16);
        SelectCmd::Make(cmd, SYS_PBOC_V2_0_PPSE, SelectCmd::First, SelectCmd::ByName);
        bool bOK = _apdu(cmd, aidData);
        if(!bOK)
        {
            bOK = pboc_get_pse_aid(SYS_PBOC_V2_0_PSE, aidlist);
        }
        else
        {
            tlv = TlvElement::Parse(aidData);
            bOK = _parse_template_aid(tlv, aidlist);
        }
        ASSERT_FuncErrInfoRet(bOK, DeviceError::OperatorErr, "PPSE/PSE枚举应用列表失败");

        ByteBuilder fullAid(8);
        bOK = pboc_final_select_aid(aidlist, fullAid, &aidData);
        ASSERT_FuncErrInfoRet(bOK, DeviceError::OperatorErr, "选择应用列表失败");

        tlv = TlvElement::Parse(terminalVal);
        TlvElement::Parse(tlv, TerminalValue);

        ByteBuilder gpo(32);
        ASSERT_FuncErrInfoRet(pboc_init_gpo(aidData, tlv, gpo), DeviceError::OperatorErr, "初始化GPO失败");
        appData.Append(gpo);

        tlv = TlvElement::Parse(gpo);
        subTlv = tlv.Select(0x5A);
        if(subTlv.IsEmpty())
            subTlv = tlv.Select(0x57);
        ASSERT_FuncErrInfoRet(!subTlv.IsEmpty(), DeviceError::RecvFormatErr, "查找卡号失败");

        ByteBuilder tmp(16);
        ByteBuilder buff(16);
        
        aidData.Clear();
        subTlv.GetValue(aidData);

        buff.Clear();
        ByteConvert::ToAscii(aidData, buff);
        size_t len = 0;
        for(;len < buff.GetLength(); ++len)
        {
            if(!_is_digital(static_cast<char>(buff[len])))
                break;
        }
        cardNumber.Append(buff.SubArray(0, len));
        return _logRetValue(true);
    }
};
//--------------------------------------------------------- 
} // namespace pboc
} // namespace application 
} // namespace zhou_yb 
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_APPLEPAY_H_
//========================================================= 